Elasticsearch Query DSL 查詢語法筆記
TLDR
- Query DSL 優勢:相比 Query String,DSL 支援 Nested 查詢、地理空間查詢、自訂評分及複雜的布林邏輯,且結構清晰易於維護。
- Match Query:全文檢索核心,
minimum_should_match僅在OR邏輯下有效,且保底值為 1。 - Multi Match:提供
best_fields(預設,取最高分)、most_fields(加總分數)、cross_fields(跨欄位搜尋)等多種策略。 - Combined Fields:以詞彙為中心,將多個 text 欄位視為單一欄位,適合跨欄位搜尋。
- Nested Query:解決 object 型別扁平化導致的關聯性丟失問題,必須用於
nested型別欄位。 - 日期範圍查詢:建議統一使用字串格式,並利用
Date Math(如||/d)處理捨入,避免數值與字串混用導致的解析錯誤。 - 效能警示:
wildcard與regexp查詢效能較差,應盡量避免使用前導萬用字元或複雜的正規表達式。
Query DSL vs Query String
在正式環境中,Query DSL(Domain Specific Language)因其 JSON 結構化特性,能提供比 Query String 更強大的功能與更明確的錯誤回饋。
1. 功能差異
某些進階功能僅能透過 Query DSL 實作:
- Nested 查詢:保留巢狀物件內部欄位關聯。
- 地理空間查詢:如
geo_distance。 - 自訂評分:使用
function_score客製化相關性評分。 - 複雜布林邏輯:透過
bool組合must、should、must_not與filter。
常用 Query DSL 語法
1. Match Query - 全文檢索查詢
用於全文檢索,會進行分詞與相關性評分。
minimum_should_match 參數
此參數僅在 operator = "OR" 時有效,用於控制至少需符合的條件數量。
- 特殊規則:最少符合數保底為 1。當設定
-4或-100%時,至少需符合 1 個詞。 - 百分比計算:採用「無條件捨去法」。例如 4 個詞設定
75%,4 × 0.75 = 3.0,至少需符合 3 個;設定74%,4 × 0.74 = 2.96,無條件捨去為 2 個。 - 多條件組合:格式如
2<-25% 9<-3,代表 ≤ 2 個 token 時需 100% 符合;3-9 個 token 時最多遺漏 25%;> 9 個 token 時最多遺漏 3 個。
lenient 參數
控制型別不符時的行為:
false(預設):拋出錯誤,查詢失敗。true:忽略該欄位查詢,不會拋出錯誤,但該欄位無匹配結果。
2. Multi Match Query - 多欄位查詢
在多個欄位中搜尋相同關鍵字。
- best_fields:取最高分欄位分數(預設)。
- most_fields:加總所有欄位分數。
- cross_fields:將多個欄位視為一個大欄位,適合姓名、地址等跨欄位匹配。
WARNING
當欄位 search_analyzer 設定不一致時,cross_fields 的行為會改變,可能導致所有詞必須在同一個欄位中出現。
3. Combined Fields Query - 跨欄位詞彙查詢
採用以詞彙為中心的方式,將多個 text 欄位視為單一組合欄位。
- 限制:所有欄位必須是
text型別且使用相同的search_analyzer。 - 執行邏輯:每個詞必須至少在一個欄位中出現(可分散在不同欄位)。
4. Range Query - 範圍查詢
用於數值與日期查詢。
- 日期格式陷阱:若 index mapping 有指定
format,查詢參數必須與之對齊,或使用format參數覆寫。 - 數值與字串混用:數值永遠被解釋為毫秒時間戳記,建議統一使用字串格式(如
"2025-01-01")以避免解析錯誤。 - 時間精度問題:若只提供到小時(如
2023-01-15T08),Elasticsearch 會將文件與查詢參數格式化至相同精度。建議明確指定完整時間或使用Date Math捨入功能(如||/h)。
5. Nested Query - 巢狀物件查詢
用於查詢 nested 型別欄位,解決 object 型別扁平化導致的關聯性丟失。
- 什麼情況下會遇到這個問題:當資料結構為陣列(如訂單中的商品列表),且需要確保「商品名稱」與「對應價格」在同一個陣列元素內匹配時。
- 解決方案:將欄位定義為
nested型別,並使用nested查詢。
json
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "term": { "comments.author": "John" }},
{ "term": { "comments.rating": 3 }}
]
}
}
}
}
}6. Fuzzy Query - 模糊查詢
容錯查詢,允許拼字錯誤。
- 建議做法:對於
text欄位,優先使用match查詢搭配fuzziness參數,而非直接使用fuzzy查詢,因為match會經過分析器處理,更符合搜尋需求。
7. Regexp Query - 正規表達式查詢
效能最差,應盡量避免。
- 錨點限制:不支援
^與$錨點運算子,正規表達式必須匹配整個字串。 - 特殊字元:若需匹配
#等特殊字元,需使用雙反斜線\\跳脫(如\\#)。
異動歷程
- 2025-11-04 初版文件建立。
